﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using lumo.display.object2D;
using System.Reflection;

namespace lumo.display.animation2D
{
    /// <summary>
    /// An angle animation for an object.
    /// </summary>
    public class PropertyAnimation<T> : GenericAnimation2D<object>
        where T : struct
    {
        // Private variables
        private T? From = null;
        private T To;
        private Counter TCounter = new Counter();
        private PropertyInfo PropertyInfo;

        /// <summary>
        /// Constructor
        /// </summary>
        public PropertyAnimation(string PropertyName, T To, float Time, Smooth Smoothness = Smooth.None, Loop LoopMode = Loop.None, object CurrentObject = null)
            : base(Time, Smoothness, LoopMode, CurrentObject)
        {
            PropertyInfo = CurrentObject.GetType().GetProperty(PropertyName);
            this.To = To;
        }

        /// <summary>
        /// Constructor
        /// </summary>
        public PropertyAnimation(string PropertyName, T? From, T To, float Time, Smooth Smoothness = Smooth.None, Loop LoopMode = Loop.None, object CurrentObject = null)
            : base(Time, Smoothness, LoopMode, CurrentObject)
        {
            PropertyInfo = CurrentObject.GetType().GetProperty(PropertyName);
            this.From = From;
            this.To = To;
        }

        /// <summary>
        /// Check if finished
        /// </summary>
        public override bool Finished { get { return (TCounter.Finished); } }

        /// <summary>
        /// Setup the values
        /// </summary>
        internal override void SetupValues()
        {
            T? from = this.From;
            if (!from.HasValue)
                from = (T)PropertyInfo.GetValue(this.CurrentObject, null);
            TCounter.Reset(Convert.ToSingle(from.Value), Convert.ToSingle(this.To), this.Time, this.Smoothness, this.LoopMode);
        }

        /// <summary>
        /// Update the values.
        /// </summary>
        /// <param name="Game">The game class</param>
        internal override void UpdateValues(LumoComponent Game)
        {
            TCounter.Update(Game);
            PropertyInfo.SetValue(this.CurrentObject, TCounter.Value, null);
        }
    }
}
